module aru_mux_2_to_1 (
    input logic              clk,
    input logic              rst_n,
          aru_mux_cfg_if.in  u_cfg_if,
          aru_payload_if.in  u_pld_in0_if,
          aru_payload_if.in  u_pld_in1_if,
          aru_payload_if.out u_pld_out_if
);

    logic     cfg_vld;
    logic     cfg_rdy;
    logic     last_req_in_instr;

    aru_dat_t dat_d1;
    aru_sdb_t sdb_d1;

    logic     has_data;
    logic     up_vld;
    logic     up_rdy;
    logic     down_vld;
    logic     down_rdy;

    assign last_req_in_instr = sdb_d1.eom && sdb_d1.eon;
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cfg_rdy <= 1'b1;
        end else if (cfg_rdy == 1'b0) begin
            if (last_req_in_instr && down_vld && down_rdy) begin
                cfg_rdy <= 1'b1;
            end
        end else begin
            if (u_cfg_if.vld && u_cfg_if.rdy) begin
                cfg_rdy <= 1'b0;
            end
        end
    end

    assign u_cfg_if.rdy = cfg_rdy;

    always_comb begin
        case (u_cfg_if.mode)
            2'b00:   up_vld = u_pld_in0_if.vld;
            2'b01:   up_vld = u_pld_in1_if.vld;
            default: up_vld = 1'b0;
        endcase
    end

    assign down_rdy = u_pld_out_if.rdy;
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            has_data <= 1'd0;
        end else if (has_data) begin
            if (~up_vld && down_rdy) begin
                has_data <= 1'd0;
            end
        end else begin
            if (up_vld) begin
                has_data <= 1'd1;
            end
        end
    end

    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            dat_d1 <= '0;
            sdb_d1 <= '0;
        end else if (up_vld && up_rdy) begin
            if (u_cfg_if.mode == 2'b00) begin
                dat_d1 <= u_pld_in0_if.dat;
                sdb_d1 <= u_pld_in0_if.sdb;
            end else if (u_cfg_if.mode == 2'b01) begin
                dat_d1 <= u_pld_in1_if.dat;
                sdb_d1 <= u_pld_in1_if.sdb;
            end
        end
    end

    assign down_vld         = has_data;
    assign up_rdy           = (~has_data) || down_rdy;

    assign cfg_vld          = ~cfg_rdy;
    assign u_pld_out_if.vld = cfg_vld && down_vld;
    assign u_pld_out_if.dat = dat_d1;
    assign u_pld_out_if.sdb = sdb_d1;
    assign u_pld_in0_if.rdy = up_rdy && cfg_vld && (u_cfg_if.mode == 2'b00);
    assign u_pld_in1_if.rdy = up_rdy && cfg_vld && (u_cfg_if.mode == 2'b01);

endmodule
